package com.hzw.video.opengl.drawer

import android.opengl.GLES20
import com.hzw.video.opengl.IDrawer
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer

/**
 *
 * @Author:         HuaZhongWei
 * @CreateDate:     2020/9/23 14:41
 *
 * @Description:
 *
 */
class TriangleDrawer() : IDrawer {

    /**
     * 顶点坐标
     */
    private val vertexCoors = floatArrayOf(
        -1f, 1f,
        0f, -1f,
        1f, 1f
    )

    /**
     * 纹理坐标
     */
    private val textureCoors = floatArrayOf(
        0f, 1f,
        1f, 1f,
        0.5f, 0f
    )

    private var program: Int = -1

    // 顶点坐标接收者
    private var vertexPosHandler: Int = -1

    // 纹理坐标接收者
    private var texturePosHandler: Int = -1

    private var textureId: Int = -1

    private var vertexBuffer: FloatBuffer
    private var textureBuffer: FloatBuffer

    init {
        vertexBuffer = ByteBuffer.allocateDirect(vertexCoors.size * 4).also {
            it.order(ByteOrder.nativeOrder())
        }.asFloatBuffer()
        vertexBuffer.put(vertexCoors)
        vertexBuffer.position(0)

        textureBuffer = ByteBuffer.allocateDirect(textureCoors.size * 4).also {
            it.order(ByteOrder.nativeOrder())
        }.asFloatBuffer()
        textureBuffer.put(textureCoors)
        textureBuffer.position(0)
    }

    override fun draw() {
        if (textureId != -1) {
            createGLProgram()
            doDraw()
        }
    }

    private fun createGLProgram() {
        if (program == -1) {
            val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, getVertexShader())
            val fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, getFragmentShader())

            program = GLES20.glCreateProgram()
            GLES20.glAttachShader(program, vertexShader)
            GLES20.glAttachShader(program, fragmentShader)
            GLES20.glLinkProgram(program)

            vertexPosHandler = GLES20.glGetAttribLocation(program, "aPosition")
            texturePosHandler = GLES20.glGetAttribLocation(program, "aCoordinate")
        }
        GLES20.glUseProgram(program)
    }

    private fun getVertexShader(): String = """
        attribute vec4 aPosition;
        void main() {
            gl_Position = aPosition;
        }
    """.trimIndent()

    private fun getFragmentShader(): String = """
        precision mediump float;
        void main() {
            gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
        }
    """.trimIndent()

    private fun loadShader(type: Int, sharedCode: String): Int = GLES20.glCreateShader(type).also {
        //将资源加入到着色器中，并编译
        GLES20.glShaderSource(it, sharedCode)
        GLES20.glCompileShader(it)
    }

    private fun doDraw() {
        //启用顶点的句柄
        GLES20.glEnableVertexAttribArray(vertexPosHandler)
        GLES20.glEnableVertexAttribArray(texturePosHandler)

        //设置着色器参数
        GLES20.glVertexAttribPointer(vertexPosHandler, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer)
        GLES20.glVertexAttribPointer(texturePosHandler, 2, GLES20.GL_FLOAT, false, 0, textureBuffer)

        //开始绘制
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 3)
    }


    override fun setTextureID(id: Int) {
        textureId = id
    }

    override fun release() {
        GLES20.glDisableVertexAttribArray(vertexPosHandler)
        GLES20.glDisableVertexAttribArray(texturePosHandler)
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0)
        GLES20.glDeleteTextures(1, intArrayOf(textureId), 0)
        GLES20.glDeleteProgram(program)
    }
}